ソフトウェアアーキテクチャの基礎輪読会 12章
日付:11/17
章:12章 マイクロカーネルアーキテクチャ
調査者:ichimura.icon
どんな内容が書かれているか
本章のざっくり理解
マイクロアーキテクチャはコアシステムとプラグインコンポーネントによるカスタマイズ性が強み
コアシステムは必要最低限の実行機能
プラグインコンポーネントは追加したい機能を切り出したもの
12.1 トポロジー
マイクロアーキテクチャとは
現在でも広く用いられているアークテクチャスタイル
インストールして使うタイプのアプリケーションのフィットしている
コアシステムとプラグインコンポーネントで構成される
恩恵
アプリケーション機能
カスタム処理ロジックの拡張性
適応性
分離性
コアシステム
例:
Eclipse IDE
基本の機能はファイルを開いて編集、保存のみ
プラグインによる拡張によって利便性を高めていく
chrome
基本のウェブ検索機能に加えて、拡張機能でカスタマイズできる
クライアント固有のカスタマイズが必要なアプリケーション
code:AssessDevice.kt
// 極端な例
class AssessiDevice(deviceID: String){
if(deviceID.equals("iPhone15"){
assassiPhone6s()
}else if(deviceID.equals("iPad4){
assassiPad4()
}else if(deviceID.equals("Pixel8"){
assassPixel8()
}else ...
...
}
プラグインコンポーネントに分離する方が優れている
code:AssessDeviceModify.kt
// デバイスごとの特殊命令を独立したプラグインにして、コアシステムはそれらを汎用的に実行するよう修正
class AssessDeviceModify(deviceID: String){
val plugin: String = pluginRegistry.get(deviceID)
val theClass = Class.forName(plugin)
val constructor = theClass.getConstructor()
val devicePlugin: DevicePlugin = constructor.newInstance() as DevicePlugin
devicePlugin.assess()
}
コアシステムも内部をドメイン固有のプラグインコンポーネントとして分割できる。
例
payment processing(支払いプロセッサ)
クレカ、PayPal、ギフトカードなどの支払い方法は支払いドメインに特化した個別のプラグインコンポーネントになる
code:引用
コアシステムのプレゼンテーション層は、コアシステム内に組み込むことも、コアシステムがバックエンドとなるサービスを提供する独立したユーザインターフェイスとして実装することもできる
例: セブン銀行
コアシステム内に実装する場合、セブンの実店舗にあるATMが該当
独立したユーザーインターフェイスとして実装する場合、スマホATMが該当
この独立したユーザーインターフェイスでもマイクロカーネルアーキテクチャを適応できる
takasshii.iconnaruhodo👀
プラグインコンポーネント
コアシステムを強化、拡張するための特殊な処理や追加機能、カスタムコードなどを含む、独立したコンポーネント。
例:IDEの拡張機能
パイプがプラグインコンポーネントのエントリーポイントクラスのメソッド、もしくは関数の呼び出しであることを示す
コンパイルベース
管理は簡単だが変更、追加、削除の際には再デプロイする必要がある
takasshii.iconアプリのアップデートとかする必要あるから場合に応じてだね
ランタイムベース
コアシステムや他のプラグインを再デプロイすることなく、実行時に追加または削除できる
管理をしてくれるフレームワーク
プラグインコンポーネントは、プロジェクト内で別々の名前空間やパッケージとして実装するという方法もある
app.plugin.<domain>.<context>
わかりやすくて、修正やテストの際に対応するプラグインを見つけやすい
リモートプラグインアクセスの場合
例
REST
メッセージング
スケーラビリティがよくなるように見えるが、まだ単なるアーキテクチャの量子にすぎない。
全てのリクエストはコアシステムを経由してからプラグインサービスに到達する
利点
OSGiやJigsaw、Prismといったフレームワークを使わずにランタイムを変更できる
プラグインとの非同期通信が可能のため、ユーザーへのレスポンス性能を大幅に向上できる
欠点
マイクロカーネルからモノリシックアーキテクチャではなく分散アーキテクチャに変えてしまう
サードパーティ製オンプレミス製品の実装やデプロイを困難にする
全体的な複雑さとコストが生み出され、デプロイメントトポロジーを複雑にする
プラグインが応答不能になったり、実行されていない場合、RESTを使用する場合はリクエストを完了できない
プロダクトの要件からこういった特徴を踏まえてポイントツーポイントにするのか、リモートにするのかを選択する
トレードオフの分析を慎重に
中央で共有されているデータベースに、プラグインコンポーネントが直接接続するのは一般的ではない
コアシステムがその責任を負い、必要なデータを各プラグインに渡す(図解)
一般的にコアシステムで共有されているデータベースにプラグインコンポーネントは接続しない
データはコアシステムからプラグインコンポーネントに渡される
データベースの変更は、コアシステムにのみ影響し、プラグインコンポーネントには与えるべきではない
疎結合な設計
それぞれのプラグインコンポーネントだけがアクセスできるデータストアを所有する設計は OK
コアシステムが利用可能なプラグインモジュールやその利用方法を知る一般的な方法
含まれる情報
プラグイン名
データコントラクト
サービスとクライアントの間の正式な取り決め
リモートアクセスプロトコルの詳細
コアシステムとプラグインの接続状態によって異なる
例:税務調査でリスクの高い項目にフラグを立てる税務ソフトのプラグイン
プラグイン名 -> AuditChecker
データコントラクト -> 入力と出力データ
コントラクト形式 -> XML
コードの例:電子機器リサイクルシステムの例
コントラクト
プラグインコンポーネントとコアシステムの間のコントラクト
動作
入力データ
プラグインコンポーネントから返される出力データ
サードパーティ製プラグインコンポーネントは、プラグインが使用するコントラクトを制御できないような状況で登場する
アダプターとなるカスタムコントラクトを作成することで対応
あくまでコアシステムが各プラグインに特化したコードを必要としないように作成する
プラグインコントラクトはXMLやJSON、プラグインとコアシステムとの間でやり取りするオブジェクトなどで実装可能
code:AssessmentOutput.kt
interface AssessmentPlugin {
fun assess(): AssessmentOutput
fun register(): String
fun deregister(): String
}
data class AssessmentOutput(
val assessmentReport: String,
val resell: Boolean,
val value: Double,
val resellPrice: Double
)
査定レポートを所定の文字列で返す
安全に廃棄できるかを表すフラグを返す
安全なら査定額と推奨再販価格を返す
これらの内容の理解はコアシステムの責任ではない
事例
Eclipse IDE
chrome
Firefox
複雑なビジネスアプリケーション
アーキテクチャ特性の評価
table:マイクロカーネルアーキテクチャ
分割タイプ ドメインと技術
量子数 1(モノリシック)
デプロイ容易性 ☆☆☆
弾力性 ☆
進化性 ☆☆☆
耐障害性 ☆
モジュール性 ☆☆☆
全体的なコスト(の安価さ) ☆☆☆☆☆
パフォーマンス ☆☆☆
信頼性 ☆☆☆
スケーラビリティ ☆
シンプルさ ☆☆☆☆
テスト容易性 ☆☆☆
劣っている点
スケーラビリティ、耐障害性、弾力性
モノリシックなデプロイメントに起因
優れている点
ドメインと技術の分割ができる
テスト容易生、信頼性
機能を独立したプラグインコンポーネントに分離できるため
モジュール性と拡張性
独立して昨日の追加、削除、変更が可能
拡張や強化はしやすい
パフォーマンス
特性上、一般的に小さいため
質疑応答